home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Games Collection 1
/
software vault.zip
/
software vault
/
CDR10
/
ACK3D.ZIP
/
ENGINE
/
ACKINIT.C
< prev
next >
Wrap
Text File
|
1993-08-23
|
10KB
|
369 lines
/******************* ( Animation Construction Kit 3D ) ***********************/
/* Initialization Routines */
/* CopyRight (c) 1993 Author: Lary Myers */
/*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys\stat.h>
#include "ack3d.h"
#include "ackeng.h"
#include "ackext.h"
#include "xtypes.h"
#include "xmslib.h"
int BuildAckTables(ACKENG *ae);
int ReadAckMapFile(char *fName);
void AckBuildHeightTables(ACKENG *ae);
void BuildAckGrid(ACKENG *ae);
/****************************************************************************
** This **MUST** be the first routine called by the application to setup **
** the ACK engine. See the file ACK3D.DOC for what fields need to be **
** setup by the application prior to making this call. **
** **
****************************************************************************/
int AckInitialize(ACKENG *ae)
{
int i,result = 0;
if (!ae->WinEndY ||
!ae->WinEndX ||
(ae->WinEndY - ae->WinStartY) < 10 ||
(ae->WinEndX - ae->WinStartX) < 10)
{
return(ERR_BADWINDOWSIZE);
}
result = BuildAckTables(ae); /* Read in TRIG.DAT and allocate tables */
if (result)
return(result);
ae->CenterRow = ae->WinStartY + ((ae->WinEndY - ae->WinStartY) / 2);
ae->WinStartOffset = ae->WinStartY * BYTES_PER_ROW;
ae->WinLength = ((ae->WinEndY - ae->WinStartY)+1) * DWORDS_PER_ROW;
ae->WinWidth = (ae->WinEndX - ae->WinStartX) + 1;
ae->WinHeight = (ae->WinEndY - ae->WinStartY) + 1;
AckBuildHeightTables(ae); /* Build height and adjustment tables */
UseXMS = 0;
#if USE_XMS
if (XMSinstalled() != FALSE)
{
if (XMSopen(1600) != FALSE)
UseXMS = 1;
else
if (XMSopen(0) != FALSE)
UseXMS = 1;
if (UseXMS)
{
for (i = 0; i < MAX_XARRAY; i++)
{
xArray[i].Bmp = (UCHAR far *)malloc(BITMAP_SIZE);
if (xArray[i].Bmp == NULL)
{
XMSclose();
return(ERR_NOMEMORY);
}
xArray[i].count = 0;
}
}
}
#endif
return(result);
}
/****************************************************************************
** Internal call to read in the TRIG.DAT file. **
** **
****************************************************************************/
int BuildAckTables(ACKENG *ae)
{
int handle,len,ca,na;
long fAng;
handle = open("trig.dat",O_RDWR|O_BINARY); /* Does file exist */
if (handle < 1)
return(ERR_BADFILE);
LongTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
LongInvTanTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
CosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
SinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
InvSinTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
InvCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
LongCosTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
xNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
yNextTable = (long far *)malloc(sizeof(long) * INT_ANGLE_360);
ViewCosTable = (long far *)malloc(sizeof(long) * VIEW_WIDTH);
Grid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
ObjGrid = (unsigned int far *)malloc((GRID_MAX * 2)+1);
AdjustTable = (long far *)malloc((MAX_DISTANCE+1) * sizeof(long));
len = ((ae->WinEndY - ae->WinStartY) + 1) * BYTES_PER_ROW;
ae->BkgdBuffer = (UCHAR far *)malloc(len);
ae->ScreenBuffer = (UCHAR far *)malloc(SCREEN_SIZE);
BitmapXferPtr = (UCHAR far *)malloc(BITMAP_SIZE+1);
if (LongTanTable == NULL ||
LongInvTanTable == NULL ||
CosTable == NULL ||
SinTable == NULL ||
InvSinTable == NULL ||
InvCosTable == NULL ||
LongCosTable == NULL ||
xNextTable == NULL ||
yNextTable == NULL ||
Grid == NULL ||
ObjGrid == NULL ||
AdjustTable == NULL ||
ae->BkgdBuffer == NULL ||
ae->ScreenBuffer == NULL ||
BitmapXferPtr == NULL ||
ViewCosTable == NULL)
{
close(handle);
return(ERR_NOMEMORY);
}
memset(ae->BkgdBuffer,0,len);
memset(ae->ScreenBuffer,0,SCREEN_SIZE);
len = sizeof(long) * INT_ANGLE_360;
read(handle,SinTable,len);
read(handle,CosTable,len);
read(handle,LongTanTable,len);
read(handle,LongInvTanTable,len);
read(handle,InvCosTable,len);
read(handle,InvSinTable,len);
read(handle,LongCosTable,len);
close(handle);
ca = INT_ANGLE_30;
na = -1;
for (len = 0; len < VIEW_WIDTH; len++)
{
ViewCosTable[len] = LongCosTable[ca];
ca += na;
if (ca <= 0)
{
ca = -ca;
na = -na;
}
}
for (len = 0; len < INT_ANGLE_360; len++)
{
yNextTable[len] = (long)GRID_SIZE * LongTanTable[len];
xNextTable[len] = (long)GRID_SIZE * LongInvTanTable[len];
}
return(0);
}
/****************************************************************************
** This routine is called by the application to read in an ACK map file. **
** The map file consist of 4096 integers for the walls followed by 4096 **
** integers for the objects. **
** **
****************************************************************************/
int AckReadMapFile(ACKENG *ae,char *fName)
{
int len,handle,rdlen;
handle = open(fName,O_RDWR|O_BINARY);
if (handle < 1)
return(ERR_BADMAPFILE);
rdlen = GRID_MAX * 2;
len = read(handle,Grid,rdlen);
if (len == rdlen)
len = read(handle,ObjGrid,rdlen);
close(handle);
if (len != rdlen)
return(ERR_READINGMAP);
BuildAckGrid(ae); /* Build wall and object XY grids */
return(0);
}
/****************************************************************************
** Internal call used to create the distance tables. Currently the distance**
** table is only used for the widths of objects. **
** **
****************************************************************************/
void AckBuildHeightTables(ACKENG *ae)
{
int i,x;
int result;
long height;
height = 18000 - ((ae->WinEndY - ae->WinStartY) * 70);
DistanceTable[0] = MAX_HEIGHT;
/************** 64 * 65536 ************/
AdjustTable[0] = 4194304L / height;
for (i = 1; i < MAX_DISTANCE; i++)
{
DistanceTable[i] = height / i;
if (height - (DistanceTable[i] * i) > (i / 2))
DistanceTable[i]++;
if (DistanceTable[i] < MIN_HEIGHT)
DistanceTable[i] = MIN_HEIGHT;
if (DistanceTable[i] > MAX_HEIGHT)
DistanceTable[i] = MAX_HEIGHT;
#if 0
AdjustTable[i] = 4194304L / DistanceTable[i];
#endif
AdjustTable[i] = 2097152L / DistanceTable[i];
}
for (i = ae->WinStartX; i < ae->WinEndX; i++)
Walls[i].LightAdj = 0;
}
UCHAR LightArray[] = {255,64,128,192,0,64,128,192,0,64,128,192,0,64,128};
/****************************************************************************
** Internal call used to process the map file into the wall and object **
** arrays. The application can use the map file for initial placement of **
** objects if desired or can setup objects itself once the map file is **
** processed. **
** **
****************************************************************************/
void BuildAckGrid(ACKENG *ae)
{
int i,j,CurIndex,pos,x1,y1;
UINT MapCode;
for (i = 0; i < MAX_DOORS; i++)
{
ae->Door[i].ColOffset = 0;
ae->Door[i].mPos = ae->Door[i].mPos1 = -1;
}
i = (GRID_WIDTH+1) * (GRID_HEIGHT+1);
memset(ae->xGrid,0,i);
memset(ae->yGrid,0,i);
CurIndex = 1;
TotalSpecial = 0;
TotalSecret = 0;
for (i = 0; i < GRID_HEIGHT; i++)
{
for (j = 0; j < GRID_WIDTH; j++)
{
pos = (i * GRID_WIDTH) + j;
MapCode = Grid[pos];
if (MapCode == MAP_STARTCODE)
{
ae->yPlayer = pos & 0xFFC0;
ae->xPlayer = (pos - ae->yPlayer) << 6;
ae->yPlayer += 32;
ae->xPlayer += 32;
continue;
}
if (MapCode == MAP_UPCODE ||
MapCode == MAP_DOWNCODE ||
MapCode == MAP_GOALCODE)
{
SpecialCodes[TotalSpecial].mPos = pos;
SpecialCodes[TotalSpecial++].mCode = MapCode;
continue;
}
if (MapCode) /* Something is in map */
{
if ((MapCode & 0xFF) != DOOR_YCODE)
{
if (ae->xGrid[pos] != DOOR_SIDECODE)
ae->xGrid[pos] = MapCode;
ae->xGrid[pos+1] = MapCode;
}
else
{
ae->xGrid[pos] = DOOR_SIDECODE;
ae->xGrid[pos+1] = DOOR_SIDECODE;
}
if ((MapCode & 0xFF) != DOOR_XCODE)
{
if (ae->yGrid[pos] != DOOR_SIDECODE)
ae->yGrid[pos] = MapCode;
ae->yGrid[pos+GRID_WIDTH] = MapCode;
}
else
{
ae->yGrid[pos] = DOOR_SIDECODE;
ae->yGrid[pos+GRID_WIDTH] = DOOR_SIDECODE;
}
}
MapCode = ObjGrid[pos];
if (MapCode)
{
CurIndex = MapCode & 0x7F;
if (CurIndex < MAX_OBJECTS)
{
x1 = (j << 6) + 32; /* Place object in center of */
y1 = (i << 6) + 32; /* the current map square */
ae->ObjList[CurIndex].x = x1;
ae->ObjList[CurIndex].y = y1;
ae->ObjList[CurIndex].mPos = pos;
ae->ObjList[CurIndex].VidRow = ae->CenterRow;
ae->ObjList[CurIndex].Active = 1;
}
}
}
}
j = 0;
for (i = 0; i < GRID_MAX; i++)
{
LightMap[i] = LightArray[j];
}
}